﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
using System.Linq;
using log4net;

namespace UPNP.IO
{
	public sealed partial class DeviceFinder
    {
        #region instance

        private readonly static Lazy<DeviceFinder> _instance = new Lazy<DeviceFinder>(
            () => new DeviceFinder(), 
            true
            );

	    public static DeviceFinder Instance
	    {
	        get
	        {
	            return _instance.Value;
	        }
	    }

        #endregion

        private readonly ILog _log = LogManager.GetLogger(typeof(DeviceFinder));
        private readonly ConcurrentDictionary<string, RootDevice> _devices = new ConcurrentDictionary<string, RootDevice>();

		public IList<RootDevice> FindInternetGateway()
		{
		    return FindByType(
                RootDeviceTypeIds.InternetGatewayDeviceType,
                RootDeviceTypeIds.InternetGatewayDslDeviceType
                );
		}

		/*public IList<RootDevice> FindWlanAccessPoint()
		{
			return FindByType(Specification.RootDeviceTypeIds.WlanAccessPointType);
		}*/

		public IList<RootDevice> FindByType(params string[] types)
		{
            if (types == null)
                throw new ArgumentNullException("types");

			// start finding
            foreach (var t in types)
            {
                SendDiscover(t);
            }
 
            // wait some seconds for responses
            Thread.Sleep(Properties.Settings.Default.DeviceFinderDiscoveryWait);

            // find all known devices
		    var ret = new List<RootDevice>();

            foreach (var t in types)
            {
                ret.AddRange(
                    from d in _devices.Values
                    where d != null
                    && d.Type == t
                    select d
                    );
            }

		    return ret.AsReadOnly();
		}

        private DeviceFinder()
        {
            StartListening();
        }

    }
}
